iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
1

此文同步於個人Blog

  • 定義


將抽象部分與實現部分分離,使它們都可以獨立的變化。

橋接模式(Bridge Pattern)是用合成關係代替繼承關係,進而降低抽象和實作的合度。

註:若對合成聚合原則不熟,可以點擊合成/聚合複用原則(Composite/Aggregate Reuse Principle)研究。

在現實生活中,有些類別是具有兩個維度或多個維度的變化。如不同顏色的LV背包。顏色跟LV背包就是兩個維度。

而剛剛提到合成代替繼承關係,舉一個買包包的例子。女朋友想要買LV,LV的款式又那麼多(若有人不知道,這邊貼心的給個連結XD),如果使用繼承的方式,包種類有背包和皮包;包的顏色有白色及黑色。我們用簡單的結構圖來看看繼承會長什麼樣子:

BP1

可以發現,一種顏色的一種包,就需要建立一個類別。類別間的耦合性相當的高,不管是要維護或是修改都非常的不容易。

  • Bridge Pattern 成員


成員 功用
Abstraction 抽象類別,定義抽象的接口,該接口包含實現具體行爲、具體特徵的Implementor接口。
RefinedAbstraction 繼承並實作Abstraction內的方法,透過合成關係呼叫Implementor內的方法。
Implementor 抽象介面,定義具體行爲、具體特徵的應用接口。
ConcreteImplementor 實作Implementor並給出接口。

Abstraction就好比LV,他裡面定義了一些方法提供RefinedAbstraction去實作,且藉由合成的方式將Implementor引入。而RefinedAbstraction就是背包或是錢包類別。Implementor則是顏色,由ConcreteImplementor實作提供真正的顏色,再經由Abstraction去呼叫使用。

BP2

我們把剛剛LV的例子帶入UML內,就會變成下圖:

BP3

Bridge Pattern 實作


剛剛看完Bridge Pattern的定義及介紹,相信都有了一些理解。現在我們把剛剛的範例寫成程式碼看看會長什麼樣子。

首先先建立Implementor並定義好其中的方法,待會讓ConcreteImplementor實作。

interface Color {
    String getColor();
}

ConcreteImplementor實作Implementor內的方法。

class White implements Color {
    public String getColor() {
        return "White";
    }
}
class Black implements Color {
    public String getColor() {
        return "Black";
    }
}

建立Abstraction類別,並將Color合成進來。

abstract class Bag {
    protected Color color;
    public void setColor(Color color) {
        this.color=color;
    }   
    public abstract String getName();
}

RefinedAbstraction繼承Abstraction,並實作其中的getName。

class Backpack extends Bag{
    public String getName() {
        return color.getColor()+"Backpack";
    }   
}

class Wallet extends Bag {
    public String getName() {
        return color.getColor()+"Wallet";
    }   
}

最後只需要把對應的物件建立組裝即可,不需要建立不同顏色的同種商品。

public class LVBag {
    public static void main(String args[]) {
        Color white = new White();
        
        Bag backpack = new Backpack();
        backpack.setColor(white);
        backpack.getName();
        
        Bag wallet = new Wallet();
        wallet.setColor(white);
        wallet.getName();
    }
}

output

White Backpack
White Wallet

藉由套用Bridge Pattern,我們解決了繼承需要產生大量類別的問題,也提升了程式整體的彈性。未來若LV種類擴充,或是顏色種類增加,只需要建立新的種類即可,不需要去影響到其他的類別。

  • 小結


Bridge Pattern的目標

將抽象部分與實現部分分離,使它們都可以獨立的變化。即用合成關係代替繼承關係。

Bridge Pattern的成員
Abstraction:抽象類別,定義抽象的接口,該接口包含實現具體行爲、具體特徵的Implementor接口。
RefinedAbstraction:繼承並實作Abstraction內的方法,透過合成關係呼叫Implementor內的方法。
Implementor:抽象介面,定義具體行爲、具體特徵的應用接口。
ConcreteImplementor:實作Implementor並給出接口。
Bridge Pattern的優缺點
優點
1. 抽象和實現的分離,提高了比繼承更好的解決方案;
2. 優秀的擴充套件能力,在兩個變化維度中任意擴充套件一個維度,都不需要修改原有系統;
3. 實現細節對客戶透明,可以對使用者隱藏實現細節。
缺點
增加系統的理解與設計難度,由於合成關聯關係建立在抽象層,要求開發者針對抽象進行設計與程式設計。
  • 範例程式碼


範例:使用Bridge Pattern

  • References


桥接模式(Bridge模式)详解
重走Java設計模式——橋接模式(Bridge Pattern)
橋接模式


上一篇
[Day15] 適配器模式 | Adapter Pattern
下一篇
[Day17] 组合模式 | Composite Pattern
系列文
從生活中認識Design Pattern30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言